#include "contact.h"

Contact::Contact()
{
	_proto.push_back(Protocol::SERVER);
	_client = new ClientManager();
	_operator[Contact::Operator::WHO] = &Contact::who;
	_operator[Contact::Operator::LIST] = &Contact::list;
	_operator[Contact::Operator::WELCOME] = &Contact::welcome;
	_operator[Contact::Operator::PING] = &Contact::ping;
}

#if defined __linux__
extern "C" __attribute__((visibility ("default"))) IModule* getContact()
#else
extern "C" __declspec(dllexport) IModule* getContact()
#endif
{
	return new Contact();
}

void					Contact::setApi(BabelApi *api)
{
	_api = api;
	_api->client = _client;
	connect(this, SIGNAL(_selectedClient(unsigned int)), dynamic_cast<QObject*>(api->gui), SLOT(receiptedClient(unsigned int)));
}

void					Contact::who(IOrder *order)
{
	unsigned int	id = *(unsigned int *)order->getData(sizeof(unsigned int));
	std::string ip("");
	ip += QString::number((*(unsigned char *)order->getData(sizeof(unsigned char)))).toStdString();
	ip += ".";
	ip += QString::number((*(unsigned char *)order->getData(sizeof(unsigned char)))).toStdString();
	ip += ".";
	ip += QString::number((*(unsigned char *)order->getData(sizeof(unsigned char)))).toStdString();
	ip += ".";
	ip += QString::number((*(unsigned char *)order->getData(sizeof(unsigned char)))).toStdString();
	std::cout << "ip : " << ip << std::endl;
	unsigned char	len = *(unsigned char *)order->getData(sizeof(unsigned char));
	std::string  name((char*)order->getData(len), len);

	Client			*client = new Client();
	client->setId(id);
	client->setIp(ip);
	client->setName(name);
	_client->add(id, client);
	refreshList();
}

void					Contact::refreshList()
{
	std::map<unsigned int, IClient *> map = _client->getMap();
	_listContact->clear();
	for (std::map<unsigned int, IClient *>::iterator it = map.begin(); it != map.end(); ++it)
	{
		QListWidgetItem		*item = new QListWidgetItem();

		item->setText(QString(it->second->getName().c_str()));
		item->setWhatsThis(QString::number(it->first));
		_listContact->addItem(item);
	}
}

void					Contact::list(IOrder *order)
{
	unsigned short	len = *(unsigned short *)order->getData(sizeof(unsigned short));
	std::cout << "LIST" << len << std::endl;
	while (len > 0)
	{
		unsigned int	id = *(unsigned int *)order->getData(sizeof(unsigned int));
		std::cout << "ID" << id << std::endl;
		if (!_client->find(id))
		{
			IOrder	*order = _api->network->getIOrder();
			order->init();
			Protocol proto = Protocol::SERVER;
			order->pushData(&proto, sizeof(proto));
			Contact::Operator op = Contact::Operator::WHO;
			order->pushData(&op, sizeof(op));
			order->pushData(&id, sizeof(id));
			_api->network->TcpSend(order);
		}
		len--;
	}
}

void					Contact::ping(IOrder *order)
{
	_api->timestamp = *(unsigned int*)order->getData(sizeof(_api->timestamp));

	_api->time.restart();

	delete order;
	Protocol			proto = SERVER;
	Operator			op = PONG;
	IOrder				*newOrder = _api->network->getIOrder();
	newOrder->init();
	newOrder->pushData(&proto, sizeof(proto));
	newOrder->pushData(&op, sizeof(op));
	_api->network->TcpSend(newOrder);
}

void					Contact::welcome(IOrder *order)
{
	OpenLoginWindow();
}

void					Contact::ConfirmLogin()
{

	Protocol			proto = SERVER;
	Operator			op = LOGIN;
	byte				size = (byte) _login->text().size();
	IOrder				*newOrder = _api->network->getIOrder();
	std::cout << "WELCOME TO THE SERVER" << std::endl;

	newOrder->init();
	newOrder->pushData(&proto, sizeof(proto));
	newOrder->pushData(&op, sizeof(op));
	newOrder->pushData(&size, sizeof(size));
	newOrder->pushData((void *)_login->text().toStdString().c_str(), size);

	size = _password->text().size();
	newOrder->pushData(&size, sizeof(size));
	newOrder->pushData((void *)_password->text().toStdString().c_str(), size);
	_api->network->TcpSend(newOrder);

	std::cout << _login->text().toStdString() << std::endl;
	std::cout << _password->text().toStdString() << std::endl;
	_loginWindow->close();
}

void					Contact::OpenLoginWindow()
{
	QVBoxLayout			*MainLayout = new QVBoxLayout();
	QHBoxLayout			*LoginLayout = new QHBoxLayout();
	QHBoxLayout			*PassWLayout = new QHBoxLayout();
	QLabel				*login = new QLabel("Login ");
	QLabel				*password = new QLabel("Password ");

	_loginWindow = new QDialog();
	_login = new QLineEdit();
	_password = new QLineEdit();
	_buttonconfirm = new QPushButton("Confirm");

	_login->setStyleSheet("QLineEdit  {"
    "border: 2px solid gray;"
    "border-radius: 10px;"
    "padding: 0 8px;"
    "}");

	_password->setStyleSheet("QLineEdit  {"
    "border: 2px solid gray;"
    "border-radius: 10px;"
    "padding: 0 8px;"
    "}");

	_buttonconfirm->setStyleSheet("QPushButton  {"
    "border: 2px solid #8f8f91;"
    "border-radius: 6px;"
    "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
                                      "stop: 0 #f6f7fa, stop: 1 #dadbde);"
    "min-width: 80px;"
"}");

	_password->setEchoMode(QLineEdit::Password);

	LoginLayout->addWidget(login);
	LoginLayout->addWidget(_login);

	PassWLayout->addWidget(password);
	PassWLayout->addWidget(_password);

	MainLayout->addLayout(LoginLayout);
	MainLayout->addLayout(PassWLayout);
	MainLayout->addWidget(_buttonconfirm);

	connect(_buttonconfirm, SIGNAL(clicked()), this, SLOT(ConfirmLogin()));

	_loginWindow->setLayout(MainLayout);
	_loginWindow->setWindowTitle("Login");
	_loginWindow->setFixedSize(300, 200);
	_loginWindow->show();
}



void					Contact::takeOrder(IOrder *order, Protocol proto)
{
	unsigned char		op = *(unsigned char *)order->getData(sizeof(op));

	if (_operator.find((Contact::Operator) op) != _operator.end())
		(this->*_operator[(Contact::Operator) op])(order);
}

void					Contact::init()
{
	addMenuContact();
	addListContact();
	_api->gui->addMenu(_menu);
	_api->gui->addWidget(_listContact);
}

void					Contact::test()
{
	std::cout << "SUCCES TEST" << std::endl;
}

std::vector<Protocol>	Contact::getProtocol() const
{
	return _proto;
}

void					Contact::addMenuContact()
{
	_menu = new QMenu("Contact");
	_addContact = _menu->addAction("Refresh");

	connect(_addContact, SIGNAL(triggered()), this, SLOT(onAddActionTriggered()));
}

void					Contact::onAddActionTriggered()
{
	IOrder	*order = _api->network->getIOrder();
	order->init();
	Protocol proto = Protocol::SERVER;
	order->pushData(&proto, sizeof(Protocol::SERVER));
	Operator op = Operator::LIST;
	order->pushData(&op, sizeof(Operator::LIST));
	_api->network->TcpSend(order);
}

void					Contact::addListContact()
{
	_listContact = new QListWidget();

	connect(_listContact, SIGNAL(itemClicked(QListWidgetItem *)), this, SLOT(userClicked(QListWidgetItem *)));

/*	IOrder	*order = _api->network->getIOrder();
	order->init();
	Protocol proto = Protocol::SERVER;
	order->pushData(&proto, sizeof(Protocol::SERVER));
	Contact::Operator op = Contact::Operator::LIST;
	order->pushData(&op, sizeof(Contact::Operator::LIST));
	_api->network->TcpSend(order);*/
}

void					Contact::userClicked(QListWidgetItem *index)
{
	std::cout << "ID : " << index->whatsThis().toStdString() << std::endl;
	emit _selectedClient(index->whatsThis().toInt());
}

Contact::~Contact()
{

}

void					User::setIdUser(int id)
{
	_id = id;
}

int						User::getIdUser() const
{
	return _id;
}
